''''''

# Standard
import logging
# Related
# Local
import moopy.errors
import moopy.mesh_element
import moopy.al.query.vertex_map


logger = logging.getLogger('moopy')

def create_map_from_index(vertex_map_index):
    '''Create a vertex map object from a vertex map index.'''

    vmap_type_switch = {
        'texture':UVMap,
        #'subweight':WeightMap,
        #'morph':MorphMap,
    }

    vmap_type = moopy.al.query.vertex_map.get_vmap_type(vertex_map_index)

    try:
        vmap_class = vmap_type_switch[vmap_type](vertex_map_index)
    except KeyError:
        raise moopy.errors.UnSupportedVertexMapTypeError()
    
    return vmap_class

def get_all_vmaps():
    ''''''
    vmap_ojects = []

    for vmap_index in moopy.al.query.vertex_map.get_all_vmap_indices():
        try:
            vmap_ojects.append(create_map_from_index(vmap_index))

        except moopy.errors.UnSupportedVertexMapTypeError:
            # This is a bad way to handle this, but for a long time
            # there will be unsupported vmap types, so this is the
            # only way this method can even be useful.
            logger.warning(
                'Moopy cannot yet create Vertex Map objects of '
                'type "%s" yet. It is being ignored inside of '
                'moopy.vertex_map.get_all_vmaps.vmaps' % (
                    moopy.al.query.vertex_map.get_vmap_type(vmap_index)
                ))

def get_selected_uv_maps():
    '''Return a list of the selected uv map objects.'''
    uv_maps = []

    for vmap_index in moopy.al.query.vertex_map.get_all_vmap_indices('texture'):

        uv_map = create_map_from_index(vmap_index)

        if uv_map.selected:
            uv_maps.append(uv_map)

    return uv_maps

class VertexMap(object):
    '''The base class for vertex maps.'''

    def __init__(self, vmap_index, *args, **kwargs):
        '''
        @param vmap_index: The vertex map index, as seen in modo. Note that
        this is not the vmap's layer order.
        '''

        #: The index of the vertex map, as seen in modo.
        self.index = vmap_index

    def __eq__(self, other):
        ''''''
        if isinstance(other, VertexMap):
            return self.index == other.index
        else:
            return NotImplemented

    def __ne__(self, other):
        ''''''
        equal = self.__eq__(other)
        if equal is NotImplemented:
            return equal
        return not equal

    def __repr__(self):
        ''''''
        return "<class 'moopy.vertex_map.VertexMap', index:%s>" % (
            self.index)

    def __str__(self):
        ''''''
        return 'Vertex Map, Name "%s"' % (self.name)

    def _get_name(self):
        ''''''
        return moopy.al.query.vertex_map.get_vmap_name(self.index)

    def _set_name(self, value):
        ''''''
        raise NotImplementedError()

    name = property(
        _get_name,
        _set_name,
        doc='''The name of the vertex map.
        '''
    )

    def _get_selected(self):
        ''''''
        return moopy.al.query.vertex_map.is_vmap_selected(self.index)

    def _set_selected(self, value):
        ''''''
        raise NotImplementedError()

    selected = property(
        _get_selected,
        _set_selected,
        doc='''Deals with the vmap list selection. Setting.. sets the
        selection, and getting.. well, gets the selection.
        Complicated right?'''
    )

class UVMap(VertexMap):
    ''''''

    def __init__(self, vmap_index, *args, **kwargs):
        ''''''
        super(UVMap, self).__init__(vmap_index, *args, **kwargs)

    def __repr__(self):
        ''''''
        return "<class 'moopy.vertex_map.UVMap', index:%s>" % (
            self.index)

    def __str__(self):
        ''''''
        return 'UV Map, Name "%s"' % (self.name)

    def get_selected_uvs(self, mesh_item):
        '''Get the selected UVVertices.

        @param mesh_item: The L{mesh item <moopy.item.Mesh>}
        that the L{uv vertices <moopy.mesh_element.UVVertex>} will be created
        from.
        '''
        uvs = moopy.al.query.mesh_element.get_selected_uvs(
            mesh_item.index, self.index)

        # If uvs is None, the user did not select any verts either in the
        # selected UVMap, or no verts at all.
        if uvs is None:
            raise NotImplementedError()
        
        def create_uvvert(uv):
            return moopy.mesh_element.UVVertex(uv[0], uv[1], mesh_item, self)

        return map(create_uvvert, uvs)

    def set_selected_uvs(self, uv_vertices):
        '''Set the selected uv vertices.

        @param uv_vertices: A collection of L{UV Vertex 
        <moopy.mesh_element.UVVertex>} objects.
        '''

        raise NotImplementedError()

class WeightMap(VertexMap):
    ''''''

    def __init__(self, *args, **kwargs):
        ''''''
        raise NotImplementedError()

    def __repr__(self):
        ''''''
        return "<class 'moopy.vertex_map.WeightMap', index:%s>" % (
            self.index)

    def __str__(self):
        ''''''
        return 'Weight Map, Name "%s"' % (self.name)

class MorphMap(VertexMap):
    ''''''

    def __init__(self, *args, **kwargs):
        ''''''
        raise NotImplementedError()

    def __repr__(self):
        ''''''
        return "<class 'moopy.vertex_map.MorphMap', index:%s>" % (
            self.index)

    def __str__(self):
        ''''''
        return 'Morph Map, Name "%s"' % (self.name)





